﻿using System;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;
using System.Web.Extensions;

namespace SoftwareDiscipline.SharePoint.UserManagement.ApplicationPages
{
    /// <summary>
    /// 
    /// </summary>
    public partial class AllUsers : LayoutsPageBase, IPostBackEventHandler
    {
        /// <summary>
        /// 
        /// </summary>
        private SqlMembershipProvider provider = null;


        /// <summary>
        /// Handles the RowDataBound event of the gvAllClients control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="GridViewRowEventArgs"/> instance containing the event data.</param>
        protected void gvAllUsers_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var menu = e.Row.FindControl<Microsoft.SharePoint.WebControls.Menu>(x => true);
                if (menu != null)
                {
                    MembershipUser user = e.Row.DataItem as MembershipUser;
                    if (user != null)
                    {
                        // check if we need to show "Approve Item" option
                        if (!user.IsLockedOut)
                        {
                            menu.HiddenMenuItems.Add(this.itemTemplateUnlockUser);
                        }

                        // check if we need to show "Edit Properties" and "Delete" options
                        if (user.IsApproved)
                        {
                            menu.HiddenMenuItems.Add(this.itemTemplateActivate);
                        }
                        else
                        {
                            menu.HiddenMenuItems.Add(this.itemTemplateDeactivate);
                        }

                        // check if the provider allows password resets
                        SqlMembershipProvider provider = this.GetMembershipProvider();
                        if (provider != null)
                        {
                            if (!provider.EnablePasswordReset)
                            {
                                menu.HiddenMenuItems.Add(this.itemTemplateResetPassword);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server.
        /// </summary>
        /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param>
        void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)
        {
            // check what type of event argument it is
            string[] eventArgs = eventArgument.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (eventArgs.Length > 0)
            {
                string operation = eventArgs[0].Trim().ToLower();
                string argument = eventArgs[1];

                Guid userId = new Guid(argument);

                SqlMembershipProvider provider = this.GetMembershipProvider();
                if (provider != null)
                {
                    MembershipUser user = provider.GetUser(userId, false);
                    if (user != null)
                    {
                        switch (operation)
                        {
                            case "delete":
                                {
                                    provider.DeleteUser(user.UserName, true);
                                    break;
                                }
                            case "activate":
                                {
                                    if (!user.IsApproved)
                                    {
                                        user.IsApproved = true;
                                        provider.UpdateUser(user);
                                    }
                                    break;
                                }
                            case "deactivate":
                                {
                                    if (user.IsApproved)
                                    {
                                        user.IsApproved = false;
                                        provider.UpdateUser(user);
                                    }
                                    break;
                                }
                            case "unlock":
                                {
                                    if (user.IsLockedOut)
                                    {
                                        user.UnlockUser();
                                        provider.UpdateUser(user);
                                    }
                                    break;
                                }
                            case "resetpassword":
                                {
                                    // reset users password and unlock the user
                                    this.ResetUserPassword(user);
                                    break;
                                }
                        }

                        this.gvAllUsers.DataBind();
                    }
                }
            }
        }

        /// <summary>
        /// Resets the user password.
        /// </summary>
        /// <param name="user">The user.</param>
        private void ResetUserPassword(MembershipUser user)
        {
            try
            {
                SqlMembershipProvider provider = this.GetMembershipProvider();
                if (provider != null)
                {
                    // first unlock the user
                    if (user.IsLockedOut)
                    {
                        user.UnlockUser();
                    }

                    // then reset the user password
                    string newPassword = user.ResetPassword();
                    if (!String.IsNullOrEmpty(newPassword))
                    {
                        // send an e-mail to the user saying their password 
                        // has been reset
                        this.SendResetPasswordNotification(user, newPassword);
                    }
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// Sends the reset password notification.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="password">The password.</param>
        private void SendResetPasswordNotification(MembershipUser user, string password)
        {
            try
            {
                // create a new mail message
                string mailMessage = this.GetResetPasswordMailMessage(user, password);

                // initialize SMTP client to send out the mail
                SmtpClient client = new SmtpClient();

                client.Send(new MailMessage(new MailAddress("administrator@localhost", "Lewis Silkin Extranet Administrator"), new MailAddress(user.Email, user.UserName))
                    {
                        Body = mailMessage,
                        Subject = this.GetGlobalResourceObject("swusrmgmt", "ResetPasswordNotification_Subject") as string
                    });
            }
            catch
            {

            }

        }

        /// <summary>
        /// Gets the reset password mail message.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <param name="password">The password.</param>
        /// <returns></returns>
        private string GetResetPasswordMailMessage(MembershipUser user, string password)
        {
            string message = this.GetGlobalResourceObject("swusrmgmt", "ResetPasswordNotification_Body") as string;
            if (!String.IsNullOrEmpty(message))
            {
                return Regex.Replace(message, @"\$\{(?<variable>[A-Za-z_0-9]+)\}", delegate(Match match)
                {
                    switch (match.Groups["variable"].Value.ToLower())
                    {
                        case "user":
                            {
                                return user.UserName;
                            }
                        case "newpassword":
                            {
                                return password;
                            }
                        default:
                            {
                                return String.Empty;
                            }
                    }
                });
            }

            return String.Empty;
        }

        /// <summary>
        /// Gets the membership provider.
        /// </summary>
        /// <returns></returns>
        private SqlMembershipProvider GetMembershipProvider()
        {
            if (this.provider == null)
            {
                SPWebApplication webApp = SPContext.Current.Site.WebApplication;
                if (webApp != null)
                {
                    // find the current zone
                    SPUrlZone currentZone = SPContext.Current.Site.Zone;

                    this.provider = webApp.GetSqlMembershipProvider(currentZone);
                }
            }

            return provider;
        }

    }
}
